package editor.osx;

import adventure.*;
import console.ANSIOutputBox;
import console.InputHistory;
import console.InputHistoryImp;
import java.awt.Color;
import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import player.*;
import server.util.Broadcaster;
import server.util.BroadcasterImp;
import server.util.PlayerConnectionLocal;
import server.util.Ticker;
import server.util.TickerImp;
import server.util.Utilities;
import server.util.tickevents.CleanupRooms;
import server.util.tickevents.ExecuteCombat;
import server.util.tickevents.RegeneratePlayers;
import server.util.tickevents.Repopulate;

/**
 *
 * @author Michael Hanns
 */
public class AdventurePreview extends javax.swing.JDialog {
    
    private Adventure adv;
    private AdventureInput advInp;
    private Player testPlayer;
    private PlayerManager pManager;
    private InputHistory hist;
    private double version = 0.2;
    private Broadcaster broadcaster;
    private Ticker serverTicker;
    private ANSIOutputBox cons;
    ExecutorService executor;

    /**
     * Creates new form AdventurePreview
     */
    public AdventurePreview(java.awt.Frame parent, boolean modal, Adventure a) {
        super(parent, modal);
        initComponents();
        this.adv = ((AdventureEdit)a).cloneThis();
        initPreview(((AdventureEdit) adv).sx(), ((AdventureEdit) adv).sy(), ((AdventureEdit) adv).sz());
    }

    /**
     * Creates new form AdventurePreview
     */
    public AdventurePreview(java.awt.Frame parent, boolean modal,
            Adventure a, int x, int y, int z) {
        super(parent, modal);
        initComponents();
        this.adv = ((AdventureEdit)a).cloneThis();
        initPreview(x, y, z);
    }

    private void initPreview(int x, int y, int z) {
        setTitle("WITNA Preview v" + version + " [" + adv.getName() + " v" + adv.getVersion() + "]");
        hist = new InputHistoryImp();
        this.cons = new ANSIOutputBox(outputBox);
        System.out.println("Currency statusID - " + adv.getCurrency().getStatusID());

        
        broadcaster = new BroadcasterImp();
        // Set up all the server side tools to work with adv
        ((AdventureEdit) adv).setBroadcaster(broadcaster);
        // Clear out the temp editor directory before reinstating the player
        File previewTempFolder = new File("/players/editorTemp/");
        if (previewTempFolder.isDirectory()) {
            previewTempFolder.delete();
        }
        pManager = new PlayerManagerImp("/players/editorTemp/" + adv.getName() + "/", adv);
        ((AdventureEdit) adv).setPlayerManager(pManager);
        inputBox.setSelectionColor(Color.ORANGE);
        inputBox.setSelectedTextColor(Color.BLACK);
        outputBox.setSelectionColor(Color.ORANGE);
        
        System.out.println("Adventurer ready?" + ((AdventureEdit)adv).ready());

        this.advInp = new AdventureInputImp(adv);
        setupTicker();
        
        this.testPlayer = pManager.getOfflinePlayer("Admin");
        ((PlayerEdit) testPlayer).setX(x);
        ((PlayerEdit) testPlayer).setY(y);
        ((PlayerEdit) testPlayer).setZ(z);
        
        broadcaster.addConnection(new PlayerConnectionLocal(testPlayer, cons));

        pManager.logOn("Admin", ((PlayerEdit) testPlayer).getPassword());
        updateGUITerminal(advInp.processCommand(testPlayer, "LOOK"));
    }

    private void setupTicker() {
        executor = Executors.newFixedThreadPool(1);
        Runnable ticker = new Runnable() {
            @Override
            public void run() {
                serverTicker = new TickerImp(adv, broadcaster, pManager);
                // Add cleanup/destroy empty corpses tick event
                serverTicker.addTickEvent(new CleanupRooms(broadcaster,
                        ((AdventureEdit) adv).getRoomManager()));
                // Add combat round event
                serverTicker.addRoundEvent(new ExecuteCombat(adv));
                // Add repop tick event
                serverTicker.addTickEvent(new Repopulate(broadcaster,
                        ((AdventureEdit) adv).getRoomManager(), pManager));
                // Add regen tick event
                serverTicker.addTickEvent(new RegeneratePlayers(pManager));
                serverTicker.startTicking();
            }
        };
        executor.submit(ticker);
    }

    protected void stopTicking() {
        System.out.println("serverTicker == null?" + (serverTicker == null));
        serverTicker.stopTicking();
        serverTicker = null;
        executor = null;
    }

    private void updateGUITerminal(String input) {
        cons.addANSIText(Utilities.wordWrap(input));
    }

    public void inputLine(String input) {
        hist.addLine(inputBox.getText());
        inputBox.setText("");
        updateGUITerminal(advInp.processCommand(testPlayer, input));
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        outputBoxPane = new javax.swing.JScrollPane();
        outputBox = new javax.swing.JTextPane();
        inputSubmit = new javax.swing.JButton();
        inputBox = new javax.swing.JFormattedTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Adventure Preview");

        outputBox.setBackground(new java.awt.Color(0, 0, 0));
        outputBox.setContentType("text/rtf");
        outputBox.setEditable(false);
        outputBox.setFont(new java.awt.Font("Courier New", 1, 14)); // NOI18N
        outputBox.setForeground(new java.awt.Color(204, 204, 204));
        outputBoxPane.setViewportView(outputBox);

        inputSubmit.setText("Submit");
        inputSubmit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputSubmitActionPerformed(evt);
            }
        });

        inputBox.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        inputBox.setFont(new java.awt.Font("Courier New", 0, 12));
        inputBox.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                inputBoxFocusLost(evt);
            }
        });
        inputBox.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                inputBoxKeyPressed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(outputBoxPane, javax.swing.GroupLayout.DEFAULT_SIZE, 699, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(inputBox, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(inputSubmit)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(outputBoxPane, javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(inputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(inputSubmit))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void inputSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputSubmitActionPerformed
        inputLine(inputBox.getText());
}//GEN-LAST:event_inputSubmitActionPerformed

    private void inputBoxFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_inputBoxFocusLost
}//GEN-LAST:event_inputBoxFocusLost

    private void inputBoxKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_inputBoxKeyPressed
        switch (evt.getKeyCode()) {
            case 38:
                inputBox.setText(hist.getLastLine());
                break;
            case 40:
                inputBox.setText(hist.getNextLine());
                break;
            case 10:
                inputLine(inputBox.getText());
                break;
        }
}//GEN-LAST:event_inputBoxKeyPressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JFormattedTextField inputBox;
    private javax.swing.JButton inputSubmit;
    private javax.swing.JTextPane outputBox;
    private javax.swing.JScrollPane outputBoxPane;
    // End of variables declaration//GEN-END:variables
}
